跳到主要内容
版本:Next

API 请求工具与封装

目录​

  1. 简介
  2. 项目架构概览
  3. 核心请求工具分析
  4. 拦截器链详解
  5. 权限与状态管理集成
  6. 错误处理机制
  7. 性能优化策略
  8. 使用示例与开发建议
  9. 故障排除指南
  10. 总结

简介​

lmes-web-base 的 API 请求工具基于 axios 封装,统一处理 HTTP 通信、权限验证、状态管理、错误提示和加载状态。

核心特性包括:

  • 自动化的 Authorization 头注入
  • Content-Type 标准化处理
  • 环境适配的 baseURL 配置
  • 携带凭据(withCredentials)支持
  • 请求拦截器集成权限校验与加载状态管理
  • 响应拦截器统一处理各种错误场景
  • 支持取消请求(CancelToken)
  • 数据预处理与转换机制
  • 国际化错误消息支持

项目架构概览​

图表来源

  • src/utils/request.ts
  • src/utils/storage.ts
  • src/libs/Language/Language.ts

核心请求工具分析​

axios 实例配置​

// baseURL 环境适配
let baseURL = ''
const params = new URLSearchParams(location.search)
baseURL = baseURL || params.get('baseURL') || ''
console.info('[baseURL]', baseURL)

// axios 实例创建
const service = axios.create({
baseURL,
headers: {},
})

核心配置特点:

  1. 动态 baseURL 适配:支持通过 URL 参数传递 baseURL,实现多环境部署
  2. 默认配置简化:移除了超时时间等硬编码配置,保持灵活性
  3. 空 headers 初始化:避免默认值干扰自定义配置

请求头自动化管理​

function appendHeaders(headers = {}) {
function withDefaultHeaders(headers: Record<string, any>) {
const token = Session.get('Token')
const defaultHeaders = {
'Content-Type': 'application/json;charset=UTF-8',
'X-Project': Session.get('X-Project'),
'X-Client-Id': localStorage.getItem('clientId'),
get Authorization() {
return token ? `Bearer ${token}` : undefined
},
get environment() {
return window.app.running ? 'runningtime' : undefined
},
get ['Accept-Language']() {
try {
return Language.getLangReqHeader()
} catch (error) {
return undefined
}
},
}
return Object.assign({}, defaultHeaders, headers)
}
return withDefaultHeaders(headers)
}

节来源

  • src/utils/request.ts

拦截器链详解​

请求拦截器流程​

图表来源

  • src/utils/request.ts

请求拦截器的核心职责:

  1. 加载状态管理:通过计数器控制全局加载指示器
  2. 请求头标准化:自动注入必要的认证和项目标识信息
  3. 数据格式化:确保 JSON 数据正确序列化
  4. 静默模式支持:允许禁用加载状态和错误提示

响应拦截器处理流程​

图表来源

  • src/utils/request.ts

节来源

  • src/utils/request.ts

权限与状态管理集成​

权限系统集成​

图表来源

  • src/libs/Permission/Permission.ts
  • src/libs/Store/Store.ts
  • src/utils/request.ts

存储系统协作​

// 本地存储封装
const Local = {
set(key: string, val: any) {
window.localStorage.setItem(key, JSON.stringify(val))
},
get(key: string) {
const value: null | string = window.localStorage.getItem(key) || null
if (!value) return null
return JSON.parse(value)
},
// ... 其他方法
}

// 会话存储封装
const Session = {
set(key: string, val: any) {
window.sessionStorage.setItem(key, JSON.stringify(val))
},
get(key: string) {
const value: null | string = window.sessionStorage.getItem(key)
try {
if (!value) return null
return JSON.parse(value)
} catch (error) {
return value
}
},
// ... 其他方法
}

节来源

  • src/utils/storage.ts

错误处理机制​

多层次错误处理​

  1. 认证错误处理

    • 401/403 状态码自动检测
    • 重新登录弹窗机制
    • 静默模式下的错误抑制
  2. 业务错误处理

    • 统一错误消息提取
    • 国际化错误提示
    • 文件下载错误特殊处理
  3. 网络错误处理

    • 超时、断网等网络异常
    • 取消请求处理
    • 代理接口不存在检测

错误消息国际化​

const message =
data?.msg ||
data?.message ||
data?.title ||
data ||
statusText ||
msg ||
'请求出错'

const loginMessage = {
'401': Language._t('登录已失效'),
'403': Language._t('禁止访问'),
}[status]

节来源

  • src/utils/request.ts

性能优化策略​

加载状态优化​

// 智能加载状态管理
let reqNum: number = 0
let loadingInstance: LoadingInstance
let lastClickTime = Date.now()

const setLoading = (silent: boolean) => {
if (silent) return

reqNum++
if (reqNum === 1) {
loadingInstance = ElLoading.service({
...loadingOptions,
customClass: `${loadingOptions.customClass} ${
Date.now() - lastClickTime < 16 ? 'locked' : ''
}`,
})
}
}

const closeLoading = (silent: boolean) => {
if (silent) return
reqNum--
if (reqNum <= 0) {
reqNum = 0
loadingInstance && loadingInstance.close()
}
}

请求合并与缓存策略​

虽然当前实现主要关注单个请求处理,但可以通过以下方式扩展:

  1. 请求去重:基于 URL 和参数的唯一性判断
  2. 响应缓存:针对 GET 请求的智能缓存机制
  3. 批量请求:支持多个请求的并发处理

节来源

  • src/utils/request.ts

使用示例与开发建议​

基础 API 调用​

// 项目配置获取
export const getProjectConfig = (name: string) => {
return request.get(`/projectApi/env?name=${name}`)
}

// 组件创建
export const createWidget = (data) => {
return request.post(`/projectApi/create`, data)
}

高级配置使用​

// 静默请求(不显示加载状态)
await request.get('/api/status', { silent: true })

// 静默错误(不显示错误提示)
await request.get('/api/check', { unLogError: true })

// 文件上传
export const postImport = (file: FormData) => {
return request({
url: `/api/v1/zc/productsop/uploadsop`,
method: 'post',
contentType: 'multipart/form-data',
headers: { accept: '*/*' },
data: file,
})
}

开发建议​

  1. 合理使用静默模式:对于后台任务或用户体验要求高的场景
  2. 错误处理策略:根据业务需求选择合适的错误处理方式
  3. 请求配置复用:通过继承和组合减少重复配置
  4. 性能监控:利用拦截器记录请求性能指标

节来源

  • src/api/project-api.ts
  • src/api/index.ts

故障排除指南​

常见问题诊断​

  1. 认证失败

    • 检查 Token 是否有效
    • 验证 Authorization 头是否正确注入
    • 确认用户会话状态
  2. 请求超时

    • 检查网络连接状态
    • 验证服务器响应时间
    • 考虑增加超时配置
  3. 跨域问题

    • 确认 CORS 配置
    • 检查代理设置
    • 验证域名匹配规则
  4. 加载状态异常

    • 检查请求计数器逻辑
    • 验证异步请求的正确关闭
    • 确认 Element Plus 加载组件配置

调试技巧​

// 启用详细日志
console.log('[Request Config]', config)
console.log('[Response Data]', response.data)

// 错误追踪
const reason = new Error(`Request Error ${status} ${method} ${url}`)
return Promise.reject(reason)

总结​

API 请求工具通过统一接口封装网络请求,业务模块可按需配置拦截器和错误处理。

核心优势​

  1. 统一的错误处理:通过响应拦截器实现了一致的错误处理策略
  2. 智能化的加载管理:基于请求计数的全局加载状态控制
  3. 权限集成:与权限管理系统对接
  4. 国际化支持:完整的多语言错误消息处理
  5. 可扩展性设计:清晰的架构便于功能扩展

技术亮点​

  • 拦截器链模式:实现了请求和响应的统一处理
  • 动态配置机制:支持运行时的灵活配置调整
  • 状态管理集成:与 Vue 状态管理配合使用
  • 资源管理:管理加载状态并释放资源